package ch.fusun.baron.client.rmi;

import java.io.IOException;

import ch.fusun.baron.core.command.GameCommand;
import ch.fusun.baron.core.command.base.CreateUserCommand;
import ch.fusun.baron.core.command.base.LoginUserCommand;
import ch.fusun.baron.core.injection.Inject;
import ch.fusun.baron.core.injection.ReInjector;
import ch.fusun.baron.core.rmi.KryoUtil;
import ch.fusun.baron.core.rmi.User;
import ch.fusun.baron.core.service.UserService;
import ch.fusun.baron.data.DataUpdate;

import com.esotericsoftware.kryonet.Client;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;

/**
 * Client implementation
 */
public class GameClient implements ClientService {

	private Client client;
	@Inject
	private UserService userService;

	/**
	 * Constructor
	 */
	public GameClient() {

	}

	/**
	 * Tries to connect to the server
	 */
	@Override
	public boolean connectToServer(String host) {
		client = new Client();
		for (Class<?> clazz : KryoUtil.getInstance()
				.getClassesForRegistration()) {
			client.getKryo().register(clazz);
		}
		client.start();
		client.addListener(new Listener() {
			@Override
			public synchronized void received(Connection arg0, Object object) {
				if (object instanceof DataUpdate) {
					DataUpdate update = (DataUpdate) object;
					ReInjector.getInstance().reInject(update);
					update.update();
				}
			}
		});
		try {
			client.connect(5000, host, 54555, 54555);
			return true;
		} catch (IOException e) {
			return false;
		}
	}

	/**
	 * @return The current user
	 */
	@Override
	public User getUser() {
		return userService.getUser();
	}

	@Override
	public void createUser(User user) {
		client.sendTCP(new CreateUserCommand(user.getName(), user.getPassword()));
		userService.setUser(user);
	}

	@Override
	public void login(String name, String password) {
		userService.setUser(new User(name, password));
		client.sendTCP(new LoginUserCommand(name, password, client.getID()));
	}

	@Override
	public void execute(GameCommand command) {
		client.sendTCP(command);
	}

}